/*
 * \brief  RAM session interface
 * \author Norman Feske
 * \date   2006-05-11
 */

/*
 * Copyright (C) 2006-2009 Norman Feske
 * Genode Labs, Feske & Helmuth Systementwicklung GbR
 *
 * This file is part of the Genode OS framework, which is distributed
 * under the terms of the GNU General Public License version 2.
 */

#ifndef _INCLUDE__RAM_SESSION__RAM_SESSION_H_
#define _INCLUDE__RAM_SESSION__RAM_SESSION_H_

#include <base/stdint.h>
#include <base/capability.h>
#include <base/exception.h>
#include <dataspace/capability.h>
#include <ram_session/capability.h>

namespace Genode {

	typedef Typed_capability<Dataspace, Dataspace_capability> Ram_dataspace_capability;

	class Ram_session
	{
		protected:

			enum Opcode {
				ALLOC, FREE, REF_ACCOUNT, TRANSFER_QUOTA, QUOTA, USED
			};

		public:

			static const char *service_name() { return "RAM"; }


			/*********************
			 ** Exception types **
			 *********************/

			class Alloc_failed   : public Exception    { };
			class Quota_exceeded : public Alloc_failed { };


			/**
			 * Destructor
			 */
			virtual ~Ram_session() { }

			/**
			 * Allocate RAM dataspace
			 *
			 * \param  size  size of RAM dataspace
			 *
			 * \throw  Quota_exceeded
			 * \return capability to new RAM dataspace
			 */
			virtual Ram_dataspace_capability alloc(size_t size) = 0;

			/**
			 * Free RAM dataspace
			 *
			 * \param ds  dataspace capability as returned by alloc
			 */
			virtual void free(Ram_dataspace_capability ds) = 0;

			/**
			 * Define reference account for the RAM session
			 *
			 * \param   ram_session    reference account
			 *
			 * \return  0 on success
			 *
			 * Each RAM session requires another RAM session as
			 * reference account to transfer quota to and from.
			 * The reference account can be defined only once.
			 */
			virtual int ref_account(Ram_session_capability ram_session) = 0;

			/**
			 * Transfer quota the another ram session
			 *
			 * \param ram_session  receiver of quota donation
			 * \param amount       amount of quota to donate
			 * \return             0 on success
			 *
			 * Quota can only be transfered if the specified
			 * RAM session is either the reference account for
			 * this session or vice versa.
			 */
			virtual int transfer_quota(Ram_session_capability ram_session, size_t amount) = 0;

			/**
			 * Return current quota limit
			 */
			virtual size_t quota() = 0;

			/**
			 * Return used quota
			 */
			virtual size_t used() = 0;

			/**
			 * Return amount of available quota
			 */
			size_t avail()
			{
				size_t q = quota(), u = used();
				return q > u ? q - u : 0;
			}
	};
}

#endif /* _INCLUDE__RAM_SESSION__RAM_SESSION_H_ */
